/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package fr.isen.web.webservicetemp.Service;

import fr.isen.web.webservicetemp.Dao.DataAccessObject;
import fr.isen.web.webservicetemp.Entity.Data;

import fr.isen.web.webservicetemp.Entity.DataSample;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

/**
 *
 * @author Maistre Louis
 */
@Service
@Scope("singleton")
public class DataService implements DataServiceInterface
{
    
    @Autowired
    DataAccessObject dao;

  
    @Override
    public void addData(Data data)
    {
        dao.addData(data);
    }
    
    @Override
    public void addDatas(List<Data> datas)
    {
        dao.addDatas(datas);
    }
    
     @Override
    public void deleteDataById(long id)
    {
        dao.deleteDataById(id);
    }
     
      @Override
    public void deleteDatabase()
    {
        dao.deleteDatabase();
    }
      
      
    @Override
    public DataSample getAllDataSample()
    {
        return dataToSample(dao.getAllData());
    }
    
     @Override
    public DataSample getAllDataSampleAverage()
    {
        return dataToSample(averagePerLocation(dao.getAllData()));
    }
    
      
     @Override
    public DataSample dataToSample(List<Data> listData)
    {
        Data dataMax = new Data();
        Data dataMin = new Data();
        
        DataSample sample = new DataSample();
         // Generation de min max      
        setDataMaxAndMinForSample(dataMax, dataMin, listData);

        sample.setDatas(listData);
        sample.setSize(sample.getDatas().size());
        sample.setDataMax(dataMax);
        sample.setDataMin(dataMin);
        return(sample);
    }
    
     @Override
    public List<Data> averagePerLocation(List<Data> datas)
    {
        ArrayList<Data> newData = new ArrayList<Data>();
        ArrayList<String> locations = new ArrayList<String>();
        Iterator itData = datas.iterator();
        while(itData.hasNext()){
            String location = ((Data)itData.next()).getLocation();
            if(!locations.contains(location))
            {
                locations.add(location);
            }
        }
        for(String location : locations)
        {
            Data data = null;
            itData = datas.iterator();
            int i=0;
            while(itData.hasNext()){
                Data actualData = (Data)itData.next();
                if(location.startsWith("FR"))
                {
                    if(!(actualData.getDataValue() < -50)){
                        if(actualData.getLocation().equals(location)){
                            if(data == null){
                                data = actualData;
                            }
                            else{
                                data.setDataValue((data.getDataValue()*i + actualData.getDataValue())/(i+1));
                            }
                            i++;
                            }
                        }
                }
            }
            if(data != null){
                newData.add(data);
            }
        }
        return(newData);
    }
    
    public Data generateRandomData()
    {
        Data data = new Data();
      
     
      
      data.setPosx(randomLong(20, -20));
      data.setPosy(data.getPosx());
      data.setPosz(randomLong(20, -20));
      
      data.setDataValue(data.getPosx()+ data.getPosy()+data.getPosz());
      
      return data;
    }
    public double randomDouble(double Max, double Min)
    {
        return Min + (Math.random() * (Max - Min));       
    }
     public long randomLong(long Max, long Min)
    {
        return (long) (Min + (Math.random() * (Max - Min)));       
    }
   
     @Override
     public List<Data> getDataBetween(Date startDate, Date endDate)
     {
         return dao.getDataBetween(startDate,endDate);
     }

   //<editor-fold defaultstate="collapsed" desc="Tools">

   void setDataMaxAndMinForSample(Data dataMax,Data dataMin, List<Data> sample)
   {     
       Data firstElement = sample.get(0);
       dataMin.setDataValue(firstElement.getDataValue());
       dataMin.setPosx(firstElement.getPosx());
       dataMin.setPosy(firstElement.getPosy());
       dataMin.setPosz(firstElement.getPosz());
       dataMax.setDataValue(firstElement.getDataValue());
       dataMax.setPosx(firstElement.getPosx());
       dataMax.setPosy(firstElement.getPosy());
       dataMax.setPosz(firstElement.getPosz());        
       
       for (Data data : sample)
       {
           setMaxOrMinForValue(dataMin,dataMax,data);
           setMaxOrMinForPosX(dataMin, dataMax, data);
           setMaxOrMinForPosY(dataMin, dataMax, data);
           setMaxOrMinForPosZ(dataMin, dataMax, data);
       }
   }
   
      
    void setMaxOrMinForValue(Data dataMin, Data dataMax, Data data)
    {
        if(data.getDataValue()< dataMin.getDataValue())
        {
            dataMin.setDataValue(data.getDataValue());
        }
        else
            if(data.getDataValue()> dataMax.getDataValue())
            {
                dataMax.setDataValue(data.getDataValue());
            }
    }
    
    void setMaxOrMinForPosX(Data dataMin, Data dataMax, Data data)
    {
        if(data.getPosx()< dataMin.getPosx())
        {
            dataMin.setPosx(data.getPosx());
        }
        else
            if(data.getPosx()> dataMax.getPosx())
            {
                dataMax.setPosx(data.getPosx());
            }
    }
    
    void setMaxOrMinForPosY(Data dataMin, Data dataMax, Data data)
    {
        if(data.getPosy()< dataMin.getPosy())
        {
            dataMin.setPosy(data.getPosy());
        }
        else
            if(data.getPosy()> dataMax.getPosy())
            {
                dataMax.setPosy(data.getPosy());
            }
    }
        
    void setMaxOrMinForPosZ(Data dataMin, Data dataMax, Data data)
    {
        if(data.getPosz()< dataMin.getPosz())
        {
            dataMin.setPosz(data.getPosz());
        }
        else
            if(data.getPosz()> dataMax.getPosz())
            {
                dataMax.setPosz(data.getPosz());
            }
    }
   //  </editor-fold>

    @Override
    public List<Data> getAllData() {
        return dao.getAllData(); 
    }

    @Override
    public Boolean hasATwin(String location, Date date) {
        return dao.hasATwin(location, date);
    }

    @Override
    public List<String> getLocation() {
        return dao.getLocation();
    }

    @Override
    public List<Data> getDataView2D(String view, Date date, String location) {
        if(view.equals("years"))
        {
        return dao.getDataView2DYears(date, location);
        }
        else if(view.equals("month"))
        {
            return dao.getDataView2DMonth(date, location);
        }
        else if(view.equals("day"))
        {
            return dao.getDataView2DDay(date, location);
        }
        return dao.getDataView2DYears(date, location);
    }
    
    
}
